package org.litepal.crud;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * This provides a send method to allow calling method in dynamic way. (Just
 * like Ruby, but not clean or easy as Ruby to use).
 * 
 * @author Tony Green
 * @since 1.1
 */
class DynamicExecutor {

	/**
	 * Disable to create an instance of DynamicExecutor.
	 */
	private DynamicExecutor() {
	}

	/**
	 * This method use java reflect API to execute method dynamically. Most
	 * importantly, it could access the methods with private modifier to break
	 * encapsulation.
	 * 
	 * @param object
	 *            The object to invoke method.
	 * @param methodName
	 *            The method name to invoke.
	 * @param parameters
	 *            The parameters.
	 * @param objectClass
	 *            Use objectClass to find method to invoke.
	 * @param parameterTypes
	 *            The parameter types.
	 * @return Returns the result of dynamically invoking method.
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	static Object send(Object object, String methodName, Object[] parameters, Class<?> objectClass,
			Class<?>[] parameterTypes) throws SecurityException, NoSuchMethodException,
			IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		if (parameters == null) {
			parameters = new Object[] {};
		}
		if (parameterTypes == null) {
			parameterTypes = new Class[] {};
		}
		Method method = objectClass.getDeclaredMethod(methodName, parameterTypes);
		method.setAccessible(true);
		return method.invoke(object, parameters);
	}

}
